#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; void Rd(int&res){ res=0;char c; while(c=getchar(),c<48); do res=res*10+(c&15); while(c=getchar(),c>47); } const int N=100005; int n,k,num[N],pos,tmp[N],len; struct Segment_Tree{ struct node{ int L,R,cnt; }tree[N<<2]; void build(int L,int R,int p){ tree[p].L=L,tree[p].R=R,tree[p].cnt=0; if(L==R)return; int mid=L+R>>1; build(L,mid,p<<1); build(mid+1,R,p<<1|1); } void up(int p){ tree[p].cnt=tree[p<<1].cnt+tree[p<<1|1].cnt; } void update(int x,int v,int p){ if(tree[p].L==tree[p].R){ tree[p].cnt+=v; return; } int mid=tree[p].L+tree[p].R>>1; if(x<=mid)update(x,v,p<<1); else update(x,v,p<<1|1); up(p); } int sum(int L,int R,int p){ if(L>R)return 0; if(tree[p].L==L&&tree[p].R==R){ return tree[p].cnt; } int mid=tree[p].L+tree[p].R>>1; if(R<=mid)return sum(L,R,p<<1); else if(L>mid)return sum(L,R,p<<1|1); else return sum(L,mid,p<<1)+sum(mid+1,R,p<<1|1); } int query(int k,int p){ if(tree[p].L==tree[p].R)return tree[p].L; int cntL=tree[p<<1].cnt; if(cntL>=k)return query(k,p<<1); else return query(k-cntL,p<<1|1); } }ST; struct BIT{ ll bit[N]; #define lowbit(x) (x&(-x)) void init(){ memset(bit,0,sizeof(bit)); } void add(int p,int v){ for(;p<=len;p+=lowbit(p))bit[p]+=v; } ll sum(int p){ ll res=0; for(;p;p-=lowbit(p))res+=bit[p]; return res; } ll query(int L,int R){ return sum(R)-sum(L-1); } }BT; ll ans; const ll inf=1LL<<60; int limL,limR,midd; void solve(int l,int r){ int p=ST.query(pos,1); int cntL=ST.sum(1,p,1),cntR=ST.sum(p+1,len,1); ll res=1LL*tmp[p]*cntL-BT.query(1,p); res+=BT.query(p+1,len)-1LL*tmp[p]*cntR; if(res<ans){ ans=res; limL=l,limR=r,midd=p; } } int main(){ Rd(n),Rd(k); pos=k+1>>1; for(int i=1;i<=n;i++)Rd(num[i]),tmp[i]=++num[i]; sort(tmp+1,tmp+1+n); len=unique(tmp+1,tmp+1+n)-tmp-1; for(int i=1;i<=n;i++)num[i]=lower_bound(tmp+1,tmp+1+len,num[i])-tmp; ST.build(1,len,1); BT.init(); for(int i=1;i<=k;i++){ ST.update(num[i],1,1); BT.add(num[i],tmp[num[i]]); } ans=inf; solve(1,k); for(int i=k+1;i<=n;i++){ ST.update(num[i-k],-1,1); BT.add(num[i-k],-tmp[num[i-k]]); ST.update(num[i],1,1); BT.add(num[i],tmp[num[i]]); solve(i-k+1,i); } cout<<ans<<endl; for(int i=1;i<=n;i++){ if(i<=limR&&i>=limL)printf("%d\n",tmp[midd]-1); else printf("%d\n",tmp[num[i]]-1); } return 0; }
|